#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <avr/wdt.h>
#ifndef F_CPU
#define F_CPU 8000000UL
#endif
#include <util/delay.h>
#include <math.h>
#define offset << 4
volatile uint8_t RGB = 0; //1 = R | 2 = G | 3 = B
volatile int Red = 1;
volatile int Blue = 1;
volatile int Green = 1;

volatile uint8_t r = 1;
volatile uint8_t g = 1;
volatile uint8_t b = 1;

volatile uint8_t status = 0; //0=start 1=Re->Ye 2=Ye->Gr 3=Gr->Cyan 4=Cyan->Bl 5=BL->Purple 6=Purple->Re

volatile uint16_t threshold = 5;

volatile uint8_t temp = 0;

void TCNT0Init(void)
{
    TCCR0 = (1<<CS01)|(1<<CS00);//divide clock by 64    8Mhz / 64 = 125000hz
    TIMSK |= (1<<TOIE0);
}

void AdcInit(void) //free running
{
    ADCSRA |= (1<<ADPS2) | (1<<ADPS1);
    ADMUX |= (1<<REFS0);
    // ADMUX |= (1<<ADLAR);
    ADCSRA |= (1<<ADFR);
    ADCSRA |= (1<<ADEN);
    ADCSRA |= (1<<ADSC);
}

int main (void)
{
    TCNT0Init();
    AdcInit();

    DDRC |= 0b00111000; //LED Output
    DDRB |= 0b00000111;

    sei();

    //
    while (1)
    {
        // uint8_t temp = ADCW;
        switch (RGB)
        {
        case 0:
            if (threshold == 5000)
            {
                threshold = 0;
                switch (status)
                {
                case 0: //Red
                    if (r !=255)
                    {
                        r = 255;
                        break;
                    }
                    else
                        status++;

                case 1: //red->Yellow
                    if (g != 255)
                    {
                        g++;
                        break;
                    }
                    else
                        status++;

                case 2: //yellow->green
                    if (r != 1)
                    {
                        r--;
                        break;
                    }
                    else
                        status++;
                case 3:
                    if (b != 255)
                    {
                        b++;
                        break;
                    }
                    else
                        status++;

                case 4:
                    if (g != 1)
                    {
                        g--;
                        break;
                    }
                    else
                        status++;

                case 5:
                    if (r != 255)
                    {
                        r++;
                        break;
                    }
                    else
                        status++;

                case 6:
                    if (b != 1)
                        b--;
                    else
                        status = 1;
                    break;
                }
            }
            else
            {
                threshold++;
            }

            Red = r;
            Green = g;
            Blue = b;
            break;
        case 1:
            Red = ADCW;
            break;

        case 2:
            Green = ADCW;
            break;

        case 3:
            Blue = ADCW;
            break;
        }
        //   float h = ((float)ADCW/1024);
        //h2rgb(h, &Red,&Green,&Blue);
    }
}

uint8_t DeBounce (void)
{
    uint8_t pinState = ((PINC & 0b00000010) >> 1);
    static uint16_t  state = 0;
    state = (state<<1) | !pinState | 0xe000;
    if (state == 0xf000) return 1;
    return 0;
}

void Display (uint8_t Redd, uint8_t Greenn, uint8_t Bluee)
{
    //if (Red != 0)
    {
        // _delay_us(delR);
        for (int i=0; i < (Redd >> 1); i++)
        {
            PORTC = 0b00001000; //Red @ PORTC3
        }
        //_delay_us(Red);
        //  PORTC = 0;
    }
    // if (Green != 0)
    {
        //  _delay_us(delG);
        for (int i=0; i < (Greenn >> 1); i++)
        {
            PORTC = 0b00010000; //Green @ PORTC3
        }
        //_delay_us(Green);
        // PORTC = 0;
    }
    //  if (Blue != 0)
    {
        //  _delay_us(delB);
        for (int i=0; i < (Bluee >> 1); i++)
        {
            PORTC = 0b00100000; //Blue @ PORTC3
        }
        //_delay_us(Blue);
    }
}

ISR(TIMER0_OVF_vect)
{
    // if (temp == 2)
    {
        temp = 0;
        if (DeBounce())
        {
            RGB++;
            if (RGB >= 4)
            {
                RGB = 1;
            }
            // _delay_ms(500);
        }

        PORTB = 0b00000001;
        Display(Red, Green, Blue);
        PORTB = 0b00000010;
        Display(Red, Green , Blue );
        PORTB = 0b00000100;
        Display(Red, Green, Blue);

        PORTB = 0;
        PORTC = 0; //clear output
    }
    // else
    //  {
    //      temp++;
    // }
}
